package com.example.paopao.passport.service.impl;

import com.alibaba.fastjson.JSON;
import com.example.paopao.common.enumerator.ServiceCode;
import com.example.paopao.common.exception.ServiceException;
import com.example.paopao.common.pojo.po.UserStatePO;
import com.example.paopao.common.pojo.security.CurrenPrincipal;
import com.example.paopao.passport.dao.cache.IUserCacheRepository;
import com.example.paopao.passport.dao.persist.repository.IUserRepository;
import com.example.paopao.passport.pojo.dto.UserLoginDTO;
import com.example.paopao.passport.pojo.vo.UserLoginInfoVo;
import com.example.paopao.passport.pojo.vo.UserLoginResultVO;
import com.example.paopao.passport.service.UserService;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

@Service
public class UserServiceImpl implements UserService {

    @Value("${paopao.jwt.secret-key}")
    private String secretKey;

    @Autowired
    private IUserCacheRepository userCacheRepository;

    @Autowired
    private IUserRepository userRepository;


    @Override
    public UserLoginResultVO login(UserLoginDTO userLoginDTO,String remoteAddr,String header) {
        UserLoginInfoVo userInfo = userRepository.getUserInfo(userLoginDTO.getUsername());
        if (userInfo==null){
            String message="登录失败,用户名或密码错误！";
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND,message);
        }

        if (!userInfo.getIsStart()){
            String message="登录失败,此账号已经被禁用！";
            throw new ServiceException(ServiceCode.ERROR_FORBIDDEN,message);
        }

        BCryptPasswordEncoder encoderPassword=new BCryptPasswordEncoder();
        boolean casePassword = encoderPassword.matches(userLoginDTO.getPassword()+secretKey, userInfo.getPassword());
        if (!casePassword){
            String message="登录失败,用户名或密码错误";
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND,message);
        }

        /*向Redis中写入此用户的启用状态与权限列表*/
        /*将权限列表转换成Json格式*/
        String authorJsonString = JSON.toJSONString(userInfo.getLimit());
        UserStatePO userStatePO=new UserStatePO();
        userStatePO.setIsStater(userInfo.getIsStart());
        userStatePO.setAuthorJsonString(authorJsonString);
        /*存入Redis*/
        userCacheRepository.savaUserState(userInfo.getId(),userStatePO);

        /*创建返回的对象*/
        UserLoginResultVO userLoginResultVO=new UserLoginResultVO();
        BeanUtils.copyProperties(userInfo,userLoginResultVO);

        /*将用户的Id与用户名生成与J问题，并存入到响应对象中*/
        Map<String,Object> map=new HashMap<>();
        map.put("id",userInfo.getId());
        map.put("username",userInfo.getUsername());
        map.put("remoteAddr",remoteAddr);
        map.put("header",header);
        String jwt= Jwts.builder()
                .setHeaderParam("alg","HS256")
                .setHeaderParam("typ","JWT")
                .setClaims(map)
                .signWith(SignatureAlgorithm.HS256,secretKey)
                .compact();
        userLoginResultVO.setToken(jwt);

        return userLoginResultVO;
    }

    @Override
    public boolean logout(CurrenPrincipal principal) {
        boolean userState = userCacheRepository.deleteUserState(principal.getUserId());
        if (!userState){
            String message="操作失败，用户数据有误！";
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND,message);
        }
        return userState;
    }
}
